package com.offcn.seckill.timer;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.offcn.seckill.dao.SeckillGoodsMapper;
import com.offcn.seckill.pojo.SeckillGoods;
import com.offcn.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.unit.DataUnit;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class SeckillGoodsPushToRedis {

    @Autowired(required = false)
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     *  1)计算秒杀时间段
     * 	2)状态必须为审核通过 status=1
     * 	3)商品实际库存个数>0
     * 	4)活动没有结束  endTime>=now()
     * 	5)在Redis中没有该商品的缓存
     * 	6)执行查询获取对应的结果集
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void loadGoodsPushToRedis(){
//        System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date()));
        // 当前要显示的时间菜单
        List<Date> dateMenus = DateUtil.getDateMenus();
        // 遍历集合
        for (Date startTime : dateMenus) {
            String ext = DateUtil.date2Str(startTime);
            QueryWrapper<SeckillGoods> queryWrapper = new QueryWrapper<>();
            // 审核通过
            queryWrapper.eq("status","1");
            // 实际库存量 > 0
            queryWrapper.gt("stock_count",0);
            // 活动没有结束
            queryWrapper.ge("start_time",DateUtil.date2StrFull(startTime));
            queryWrapper.lt("end_time",DateUtil.date2StrFull(DateUtil.addDateHour(startTime,2)));
            // 获取已经在redis中的商品的ID
            Set ids = stringRedisTemplate.boundHashOps("seckillGoods_" + ext).keys();
            // 在Redis中没有该商品的缓存
            if (ids != null && ids.size() > 0) {
                queryWrapper.notIn("id",ids);
            }
            // 查询
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(queryWrapper);
            // 将查询的内容存入到redis
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                stringRedisTemplate.boundHashOps("seckillGoods_" + ext)
                        .put(seckillGoods.getId().toString(), JSON.toJSONString(seckillGoods));
                // 两个小时的有效时间  11:45导入数据， 11:59失效
                // 活动的结束时间
                Date endTime = DateUtil.addDateHour(startTime, 2);
                stringRedisTemplate.expire("seckillGoods_" + ext, endTime.getTime()-new Date().getTime(), TimeUnit.MILLISECONDS);

                // 从当前时间开始计算，2个小时之后失效
//                stringRedisTemplate.expire("seckillGoods_" + ext, Duration.ofHours(2));

                // 将 商品的Id 按照 个数 存入到redis
                String[] idArr = pushIds(seckillGoods.getStockCount(), seckillGoods.getId().toString());
                stringRedisTemplate.boundListOps("seckillGoodsCountList_" + seckillGoods.getId()).leftPushAll(idArr);

                // 自增计数器
                stringRedisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillGoods.getId().toString(),seckillGoods.getStockCount());
            }
        }

    }

    /**
     * 将 个数为 length 个 id 存入一个数组中
     * @param length
     * @param id
     * @return
     */
    public String[] pushIds(int length,String id) {
        String[] ids = new String[length];
        for (int i = 0; i < ids.length; i++) {
            ids[i] = id;
        }
        return ids;
    }
}
